home *** CD-ROM | disk | FTP | other *** search
Text File | 2000-09-28 | 7.4 KB | 347 lines | [TEXT/CWIE] |
- //• ------------------------------------------------------------------------------------------ •
- //•
- //• Copyright © 1996 Apple Computer, Inc., All Rights Reserved
- //•
- //•
- //• You may incorporate this sample code into your applications without
- //• restriction, though the sample code has been provided "AS IS" and the
- //• responsibility for its operation is 100% yours. However, what you are
- //• not permitted to do is to redistribute the source as "DSC Sample Code"
- //• after having made changes. If you're going to re-distribute the source,
- //• we require that you make it clear in the source that the code was
- //• descended from Apple Sample Code, but that you've made changes.
- //•
- //• Authors:
- //• Chris De Salvo
- //•
- //• ------------------------------------------------------------------------------------------ •
-
- /*
- These memory routines are kinda handy and solve a lot of problems on the Mac when dealing
- with memory. For instance, people often call DisposeHandle() when they mean to call
- ReleaseResource() and it screws up their resource chain. DisposeHandleZ() checks to see
- if the handle is locked or not, and whether it's a resource or not and takes the appropriate
- action.
-
- All functions ending in 'Z' take the ADDRESS of the Ptr/Handle and set it to nil when it
- disposes of the memory. This is handy because you can then do things like this:
-
- foo = NewPtr();
- DisposePtrZ(&foo);
- ...
- ...
-
- if (foo)
- ...
-
- Probably the most useful of all this stuff are the tagged Ptr and tagged Handle functions.
- Basically what they do is add 12 bytes to the beginning of every block of memory that you
- allocate. The first four bytes are the value kBlockTag. The second is an OSType that
- you provide. The 3rd group of four bytes is a refcon that you provide. This is really
- usefull when working with ZoneRanger or other memory watching tool because when you view
- a block of memory you can see your type and refcon and get a clue as to what the memory
- is. It's really great when you have a memory leak and can't tell what's not getting
- deallocated. Another use is for tracking resources. Pass in the resource type as the
- OSType field and the resource number in the refcon. Then in ZoneRanger you can see
- exactly which resource and number a handle is.
-
- Another use is for reference counting list of similar objects. If you allocate 200 foos
- then set the OSType to 'foo ' and make the refcon the index of which foo it is. This is
- helpful for finding off-by-one loop errors when deallocating lists and arrays.
-
- One other thing that has come in really handy is to set the OSType to some identifier saying
- which source file the block was allocated in and setting the refcon to the line number in
- that source file. That way in ZoneRanger you can tell exactly where that mystery block
- came from.
- */
-
- //• ------------------------------ Includes
-
- #include <Resources.h>
-
- #include <string.h>
-
- #include "MemoryHandler.h"
-
- //• ------------------------------ Private Definitions
-
- #define kBlockTag "TBLK"
-
- //• ------------------------------ Private Types
- //• ------------------------------ Private Variables
- //• ------------------------------ Private Functions
- //• ------------------------------ Public Variables
-
- //• -------------------- IsResourceHandle
-
- Boolean
- IsResourceHandle(Handle theHandle)
- {
- SInt8 memState;
-
- memState = HGetState(theHandle);
-
- //• Check the resource bit in the handle info
- if (memState & 0x20)
- return (true);
-
- return (false);
- }
- //• -------------------- IsLockedHandle
-
- Boolean
- IsLockedHandle(Handle theHandle)
- {
- SInt8 memState;
-
- //• Check the lock bit in the handle info
- memState = HGetState(theHandle);
-
- if (memState & 0x80)
- return (true);
-
- return (false);
- }
-
- //• -------------------- DisposeControlZ
-
- void
- DisposeControlZ(ControlHandle *theControl)
- {
- if (! (**theControl))
- return;
-
- if (IsLockedHandle((Handle) *theControl))
- HUnlock((Handle) *theControl);
-
- DisposeControl(*theControl);
- *theControl = nil;
- }
-
- //• -------------------- DisposeWindowZ
-
- void
- DisposeWindowZ(WindowRef *theWindow)
- {
- if (! *theWindow)
- return;
-
- DisposeWindow(*theWindow);
- *theWindow = nil;
- }
-
- //• -------------------- DisposeDialogZ
-
- void
- DisposeDialogZ(DialogPtr *theWindow)
- {
- if (! *theWindow)
- return;
-
- DisposeDialog(*theWindow);
- *theWindow = nil;
- }
-
- //• -------------------- DisposeGWorldZ
-
- void
- DisposeGWorldZ(GWorldPtr *theGWorld)
- {
- if (! *theGWorld)
- return;
-
- if (IsLockedHandle((Handle) GetGWorldPixMap(*theGWorld)))
- UnlockPixels(GetGWorldPixMap(*theGWorld));
-
- DisposeGWorld(*theGWorld);
- *theGWorld = nil;
- }
-
- //• -------------------- DisposePaletteZ
-
- void
- DisposePaletteZ(PaletteHandle *thePal)
- {
- if (! *thePal)
- return;
-
- if (IsResourceHandle((Handle) *thePal))
- ReleaseResource((Handle) *thePal);
- else
- DisposePalette(*thePal);
-
- *thePal = nil;
- }
-
- //• -------------------- KillPictureZ
-
- void
- KillPictureZ(PicHandle *thePicture)
- {
- if (! (**thePicture))
- return;
-
- if (IsLockedHandle((Handle) *thePicture))
- HUnlock((Handle) *thePicture);
-
- if (IsResourceHandle((Handle) *thePicture))
- ReleaseResource((Handle) *thePicture);
- else
- KillPicture(*thePicture);
-
- *thePicture = nil;
- }
-
- //• -------------------- DisposePtrZ
-
- void
- DisposePtrZ(Ptr *thePtr)
- {
- if (! *thePtr)
- return;
-
- DisposePtr(*thePtr);
- *thePtr = nil;
- }
-
- //• -------------------- DisposeHandleZ
-
- void
- DisposeHandleZ(Handle *theHandle)
- {
- if (! (**theHandle))
- return;
-
- if (IsLockedHandle(*theHandle))
- HUnlock(*theHandle);
-
- if (IsResourceHandle(*theHandle))
- ReleaseResource(*theHandle);
- else
- DisposeHandle(*theHandle);
-
- *theHandle = nil;
- }
-
- //• -------------------- TEDisposeZ
-
- void
- TEDisposeZ(TEHandle *theHandle)
- {
- if (! (**theHandle))
- return;
-
- if (IsLockedHandle((Handle) *theHandle))
- HUnlock((Handle) *theHandle);
-
- if (IsResourceHandle((Handle) *theHandle))
- ReleaseResource((Handle) *theHandle);
- else
- TEDispose(*theHandle);
- }
-
- //• -------------------- LDisposeZ
-
- void
- LDisposeZ(ListHandle *theHandle)
- {
- if (! (**theHandle))
- return;
-
- if (IsLockedHandle((Handle) *theHandle))
- HUnlock((Handle) *theHandle);
-
- if (IsResourceHandle((Handle) *theHandle))
- ReleaseResource((Handle) *theHandle);
- else
- LDispose(*theHandle);
- }
-
- //• -------------------- PurgeAndCompactMem
-
- void
- PurgeAndCompactMem()
- {
- Size growSize;
-
- MaxMem(&growSize);
- }
-
- //• -------------------- NewTaggedPtr
-
- Ptr
- NewTaggedPtr(Size size, OSType tag, UInt32 refCon)
- {
- Ptr thePtr;
-
- size += 12;
-
- thePtr = NewPtr(size);
- if (! thePtr)
- return (nil);
-
- BlockMoveData(kBlockTag, thePtr, 4);
- BlockMoveData(&tag, thePtr + 4, 4);
- BlockMoveData(&refCon, thePtr + 8, 4);
-
- return (thePtr + 12);
- }
-
- //• -------------------- NewTaggedPtrClear
-
- Ptr
- NewTaggedPtrClear(Size size, OSType tag, UInt32 refCon)
- {
- Ptr thePtr;
-
- size += 12;
-
- thePtr = NewPtrClear(size);
- if (! thePtr)
- return (nil);
-
- BlockMoveData(kBlockTag, thePtr, 4);
- BlockMoveData(&tag, thePtr + 4, 4);
- BlockMoveData(&refCon, thePtr + 8, 4);
-
- return (thePtr + 12);
- }
-
- //• -------------------- DisposeTaggedPtr
-
- void
- DisposeTaggedPtr(Ptr thePtr)
- {
- Ptr ptr2;
-
- if (! thePtr)
- return;
-
- ptr2 = thePtr - 12;
-
- //• Confirm that this is one of our tagged blocks first
- if (strncmp(kBlockTag, ptr2, 4) == 0)
- DisposePtr(ptr2);
- else
- DisposePtr(thePtr);
- }
-
- //• -------------------- DisposeTaggedPtrZ
-
- void
- DisposeTaggedPtrZ(Ptr *thePtr)
- {
- Ptr ptr2;
-
- if (! *thePtr)
- return;
-
- ptr2 = (*thePtr) - 12;
- if (strncmp(kBlockTag, ptr2, 4) == 0)
- DisposePtr(ptr2);
- else
- DisposePtr(*thePtr);
-
- *thePtr = nil;
- }
-